package com.newhero.product.module.sys.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.newhero.product.common.controller.BaseController;
import com.newhero.product.common.csrf.CsrfToken;
import com.newhero.product.common.util.CaptchaUtils;
import com.newhero.product.common.util.ServerUtil;
import com.newhero.product.common.util.StringUtils;
import com.newhero.product.common.util.SystemInfo;
import com.newhero.product.common.vo.Json;
import com.newhero.product.module.sys.model.Config;
import com.newhero.product.module.sys.service.IAppService;
import com.newhero.product.module.sys.service.IConfigService;
import com.newhero.security.LicenseUtil;
import com.newhero.security.NewheroLicense;
import com.newhero.security.PubRSAUtil;

/**
 * @ClassName: IndexController
 * @Description: 后台登录、主页控制类
 * @author Caolj 648198687@qq.com
 * @date 2017-3-22 下午1:49:08
 */
@Controller
@RequestMapping("/admin")
public class IndexController extends BaseController {

	@Autowired
	private IAppService appServiceImpl;
	@Autowired
	private IConfigService configServiceImpl;

	@GetMapping("")
	public String no() {
		return "redirect:/admin/index";
	}

	@GetMapping("/")
	public String index() {
		return "redirect:/admin/index";
	}

	@GetMapping("/index")
	public String index(Model model) {

		String userID = super.getUserID();

		List<Map<String, Object>> topMenuList = appServiceImpl
				.getTopMenuListWithAuth(userID);
		model.addAttribute("topMenuList", topMenuList);

		List<Map<String, Object>> secondLevelMenuList = appServiceImpl
				.getNextLevelMenuListWithAuth(userID, topMenuList);
		
		model.addAttribute("secondLevelMenuList", secondLevelMenuList);
		model.addAttribute("userName", super.getUserName());

		return "sys/index";
	}

	@GetMapping("/login")
	@CsrfToken(create = true)
	public String login(HttpServletRequest request) {
//		String returnUrl = request.getParameter(SSOConfig.getInstance().getParamReturl());
//		SSOToken token = SSOHelper.getSSOToken(request);
//		if (token == null) {
//			SSOToken st = new SSOToken();
//			SSOToken.create();
//			SSOHelper.setCookie(request, response, st, true);
////			SSOHelper.setSSOCookie(request, response, st, true);
//		}else{
//			WafRequestWrapper wr = new WafRequestWrapper(request);
//			String name = wr.getParameter("userid");
//			
//		}
		
		
		logger.info("GET请求登录");
		if (SecurityUtils.getSubject().isAuthenticated()) {
			return "redirect:/admin/index";
		}
		// 1-需要验证码 0-不用验证码
		String needVC = configServiceImpl.getConfigItemValue(_ITEM_ADMIN_VERIFICATIONCODE);
		request.setAttribute("needVC", needVC);
		return "sys/login";
	}

	@PostMapping("/login")
	@CsrfToken(remove = true)
	@ResponseBody
	public Object loginPost(
			HttpServletRequest request,
			String userLoginName,
			String userPwd,
			String captcha,
			@RequestParam(value = "rememberMe", defaultValue = "1") Integer rememberMe) {
		logger.info("POST请求登录");
		
		// 1-需要验证码 0-不用验证码
		String needVC = configServiceImpl
				.getConfigItemValue(_ITEM_ADMIN_VERIFICATIONCODE);
		// 改为全部抛出异常，避免ajax csrf token被刷新
		if (StringUtils.isBlank(userLoginName)) {
			throw new RuntimeException("用户名不能为空");
		}
		if (StringUtils.isBlank(userPwd)) {
			throw new RuntimeException("密码不能为空");
		}
		if (needVC != null && "1".equals(needVC.trim())) {
			if (StringUtils.isBlank(captcha)) {
				throw new RuntimeException("验证码不能为空");
			}
			if (!CaptchaUtils.validate(request, captcha)) {
				throw new RuntimeException("验证码错误");
			}
		}

		Subject user = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken(userLoginName,
				userPwd);
		// 设置记住密码
		// token.setRememberMe(1 == rememberMe);
		try {
			user.login(token);
			return renderSuccess();
		} catch (UnknownAccountException e) {
			throw new RuntimeException("账号不存在！", e);
		} catch (DisabledAccountException e) {
			throw new RuntimeException("账号未启用！", e);
		} catch (IncorrectCredentialsException e) {
			throw new RuntimeException("密码错误！", e);
		} catch (Throwable e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}
	
	@PostMapping("/checkVersion")
	@ResponseBody
	public Json checkVersion(){
		Json json = new Json();
		json.setSuccess(true);
		//-1试用期到
		//-2授权出错
		// 0正式版
		// 1正常试用中
		if(!LicenseUtil.checkLicense()){
			//系统名称分为三类：NEWHERO，TEST，TESTDEV
			if(!"NEWHERO".equals(LicenseUtil.getSystemLicense())){
				json.setMsg("-1");
				json.setObj("试用版本已经到期，请联系软件厂商！");
			}else{
				json.setMsg("-2");
				json.setObj("当前软件在服务器注册错误，请核对正版授权的License！");
			}
			
		}else{
			if("NEWHERO".equals(LicenseUtil.getSystemLicense())){
				json.setMsg("unlimited");
			}else{
				String licenseDate = new String(PubRSAUtil.decrypt(NewheroLicense.getInstance().getThisLicense())).split(";")[2];
				json.setMsg(licenseDate);
			}
		}
		return json;
	}

	/**
	 * 未授权
	 * 
	 * @return {String}
	 */
	@GetMapping("/unauth")
	public String unauth() {
		if (SecurityUtils.getSubject().isAuthenticated() == false) {
			return "redirect:/login";
		}
		return "unauth";
	}

	@GetMapping("/welcome")
	public String welcome(HttpServletRequest request) {
		
		String serverID = ServerUtil.getServerId();

		SystemInfo si = SystemInfo.getInstance(request);

		String jvmTotal = String
				.valueOf(Runtime.getRuntime().totalMemory() / 1024 / 1024);// totalMemory()获取java虚拟机中的内存总量
		String jvmFree = String
				.valueOf(Runtime.getRuntime().freeMemory() / 1024 / 1024);// freeMemory()获取java虚拟机中的空闲内存量
		String jvmMax = String
				.valueOf(Runtime.getRuntime().maxMemory() / 1024 / 1024);// maxMemory()获取java虚拟机试图使用的最大内存量

		Map<String, String> dataMap = new HashMap<String, String>();
		dataMap.put("serverName", serverID);
		dataMap.put("jdkVersion", si.getJava_version());
		dataMap.put("jvmTotal", jvmTotal);
		dataMap.put("jvmFree", jvmFree);
		dataMap.put("jvmMax", jvmMax);
		dataMap.put("osName", si.getOs_name());
		dataMap.put("osArch", si.getOs_arch());
		dataMap.put("serverIP", si.getOs_ip());
		dataMap.put("serverMAC", si.getOs_mac());
		dataMap.put("cpuNum", si.getOs_cpus().toString());
		request.setAttribute("dataMap", dataMap);
		return "sys/welcome";
	}

	@GetMapping("/captcha.jpg")
	public void captcha(HttpServletRequest request, HttpServletResponse response) {
		CaptchaUtils.generate(request, response);
	}

	@GetMapping(value = "/tmenu")
	public String tmenu(@RequestParam(value = "id", required = true) String id,
			HttpServletRequest request, HttpServletResponse response) {
		String userID = super.getUserID();
		
		
		
		List<Map<String, Object>> thirdLevelMenuList = appServiceImpl
				.getNextLevelMenuListWithAuth(userID, id);
		List<Map<String, Object>> fourthLevelMenuList = appServiceImpl
				.getNextLevelMenuListWithAuth(userID, thirdLevelMenuList);

		request.setAttribute("thirdLevelMenuList", thirdLevelMenuList);
		request.setAttribute("fourthLevelMenuList", fourthLevelMenuList);
		request.setAttribute("appName", appServiceImpl.selectById(id)
				.getAppName());
		return "sys/tmenu";
	}

	/**
	 * 退出
	 * 
	 * @return {Result}
	 */
	@GetMapping("/logOut")
	public Object logout() {
		logger.info("登出");
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
		return "redirect:/admin/login";
	}

}
